package com.koron.common.web.service;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.koron.common.web.bean.DepartmentBean;
import com.koron.common.web.bean.StaffBean;
import com.koron.common.web.mapper.DepartmentMapper;
import com.koron.common.web.mapper.StaffDepartmentRelationMapper;
import com.koron.common.web.mapper.StaffMapper;
import com.koron.css2.common.utils.HttpUtils;
import com.koron.util.Constant;
import com.koron.util.JsonUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.koron.ebs.mybatis.ADOConnection;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.SqlTask;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service("old")
public class SynchronizationOrgService implements ISynchronizationOrgService{
    
	private static final Logger LOG = LogManager.getLogger(SynchronizationOrgService.class);

	@Value("${app.syn_org_url}")
	private String synOrgUrl;
	
	@Value("${app.syn_department_url}")
	private String synDepartmentUrl;
	
	@Value("${app.syn_staff_url}")
	private String synStaffUrl;
	
	@Value("${app.syn_staff_department_url}")
	private String synStaffDepartmentUrl;
	
	private static String root;
	
	public static String getRoot() {
		return root;
	}

	@Value("${app.syn_org_root}")
	public void setRoot(String root) {
		SynchronizationOrgService.root = root;
	}

	private static final int BATCH_COUNT = 500;
	
	@Override
	public MessageBean<?> synchronization(SessionFactory factory) {
		try {
			return ADOConnection.runTask(new SqlTask() {
				@Override
				public Object run(SessionFactory factory) {
					synDepartment(factory);  // 插入部门
    				synStaff(factory);       //插入员工
					return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "执行成功", Void.class);
				}
			}, MessageBean.class);
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("组织架构同步失败!!!!!!!" + e);
		}
		return MessageBean.create(-1, "执行失败", Void.class);
	}
	
	@Override
	public MessageBean<?> synDepartment(SessionFactory factory) {
		initDepartment(factory);
		String data = HttpUtils.sendGetForm(synDepartmentUrl, null);
		MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
		if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
			LOG.error(message.getDescription());
			throw new RuntimeException("调用数据同步接口失败:" + message.getDescription());
		}
		JsonElement jsonElement = new Gson().toJsonTree(message.getData());
		JsonArray jsonArray = jsonElement.getAsJsonArray();
		Iterator<JsonElement> iterator = jsonArray.iterator();
		List<DepartmentBean> deparmentList = new ArrayList<DepartmentBean>();
		while(iterator.hasNext()) {
			JsonElement json = iterator.next();
			deparmentList.add(newDepartment(json));
		}
		if(deparmentList != null && deparmentList.size() > 0) {
			batchInsertDepartment(factory, deparmentList);
		}
		return null;
	}

	@Override
	public MessageBean<?> synOrg(SessionFactory factory) {
		return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "执行成功", Void.class);
	}

	@Override
	public MessageBean<?> synStaff(SessionFactory factory) {
		initStaff(factory);
		initStaffDepartment(factory);
		String data = HttpUtils.sendGetForm(synStaffUrl, null);
		MessageBean<?> message = JsonUtils.jsonToPojo(data, MessageBean.class);
		if(message.getCode() != Constant.MESSAGE_INT_SUCCESS) {
			LOG.error(message.getDescription());
			throw new RuntimeException("调用数据同步接口失败:" + message.getDescription());
		}
		JsonElement jsonElement = new Gson().toJsonTree(message.getData());
		JsonArray jsonArray = jsonElement.getAsJsonArray();
		Iterator<JsonElement> iterator = jsonArray.iterator();
		List<StaffBean> staffSize = new ArrayList<StaffBean>();
		while(iterator.hasNext()) {
			JsonElement json = iterator.next();
			staffSize.add(newStaff(json));
		}
		LOG.info("员工数量：{}", staffSize.size());
		if(staffSize != null && staffSize.size() > 0) {
			batchInsertStaff(factory, staffSize);
		}
		return null;
	}

	@Override
	public MessageBean<?> synStaffDepartmentRelation(SessionFactory factory) {
		initStaffDepartment(factory);
		return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "同步员工部门成功", Void.class);
	}
	
	@Scheduled(cron = "0 50 23 * * ?")
	public MessageBean<?> synchronization() {
		try {
			return ADOConnection.runTask(new SqlTask() {
				@Override
				public Object run(SessionFactory factory) {
					synDepartment(factory); // 插入部门
					synStaff(factory); //插入员工
					return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "执行成功", Void.class);
				}
			}, MessageBean.class);
		}catch (Exception e) {
			e.printStackTrace();
			LOG.error("组织架构同步失败!!!!!!!" + e);
		}
		return MessageBean.create(-1, "执行失败", Void.class);
	}
	
	private boolean initStaffDepartment(SessionFactory factory) {
		StaffDepartmentRelationMapper mapper = factory.getMapper(StaffDepartmentRelationMapper.class);
		int iCount = mapper.deleteAll();
		if(iCount > 0) {
			LOG.info("删除组织人员部门关系表成功：{}", iCount);
			return true;
		}
		return false;
	}
	
	private void initDepartment(SessionFactory factory) {
		DepartmentMapper mapper = factory.getMapper(DepartmentMapper.class);
		int iCount = mapper.deleteAll();
		if(iCount > 0) {
			LOG.info("删除组织架构成功：{}", iCount);
		}
	}
	
	private void initStaff(SessionFactory factory) {
		StaffMapper mapper = factory.getMapper(StaffMapper.class);
		int iCount = mapper.deleteAll();
		if(iCount > 0) {
			LOG.info("删除员工信息成功：{}", iCount);
		}
	}
	
	private void batchInsertDepartment(SessionFactory factory, List<DepartmentBean> deparmentList) {
		DepartmentMapper mapper = factory.getMapper(DepartmentMapper.class);
		int iCount = mapper.batchInsertDepartment(deparmentList);
		if(iCount > 0) {
			LOG.info("组织架构同步成功：{}", iCount);
		}
	}
	
	private void batchInsertStaff(SessionFactory factory, List<StaffBean> staffList) {
		StaffMapper mapper = factory.getMapper(StaffMapper.class);
		if(staffList.size() <= BATCH_COUNT) {
			int iCount = mapper.batchInsertStaff(staffList);
			if(iCount > 0) {
				LOG.info("员工信息同步成功：{}", iCount);
			}
			iCount = mapper.batchInsertStaffDepartment(staffList);
			if(iCount > 0) {
				LOG.info("员工部门信息同步成功：{}", iCount);
			}
		} else {
			int size = staffList.size() / BATCH_COUNT;
			int remainder = staffList.size() % BATCH_COUNT;
			for(int i = 0; i < size; i++) {
				int fromIndex = i * BATCH_COUNT;
				int toIndex = (i + 1) * BATCH_COUNT;
				if((i + 1) == size && remainder > 0) {
					toIndex = toIndex + remainder;
				}
				int iCount = mapper.batchInsertStaff(staffList.subList(fromIndex, toIndex));
				if(iCount > 0) {
					LOG.info("员工信息同步成功：{}", iCount);
				}
				iCount = mapper.batchInsertStaffDepartment(staffList.subList(fromIndex, toIndex));
				if(iCount > 0) {
					LOG.info("员工部门信息同步成功：{}", iCount);
				}
			}
		}
	}
	
	private DepartmentBean newDepartment(JsonElement jsonElement) {
		DepartmentBean department = new DepartmentBean();
		JsonObject jsonObject = jsonElement.getAsJsonObject();
		if(jsonObject.get("name") != null) {
			department.setName(jsonObject.get("name").getAsString());
		}
		if(jsonObject.get("description") != null) {
			department.setDescription(jsonObject.get("description").getAsString());
		} 
		if(jsonObject.get("orgKind") != null) {
			department.setFlag(jsonObject.get("orgKind").getAsInt());
		}
		if(jsonObject.get("shortname") != null) {
			department.setShortname(jsonObject.get("shortname").getAsString());
		}
		if(jsonObject.get("weight") != null) {
			department.setSn(jsonObject.get("weight").getAsInt());
		}
		if(jsonObject.get("status") != null) {
			department.setState(jsonObject.get("status").getAsInt() == 1 ? 0 : 1);
		}
		if(jsonObject.get("phone") != null) {
			department.setTel(jsonObject.get("phone").getAsString());
		}
		if(jsonObject.get("code") != null) {
			department.setCode(jsonObject.get("code").getAsString());
		}
		if(jsonObject.get("parentCode") != null) {
			department.setParentcode(jsonObject.get("parentCode").getAsString());
		} else {
			department.setParentcode(getRoot());
		}
		return department;
	}
	
	private StaffBean newStaff(JsonElement jsonElement) {
		JsonObject jsonObject = jsonElement.getAsJsonObject();
		StaffBean staff = new StaffBean();
		if(jsonObject.get("loginName") != null) {
			staff.setLoginid(jsonObject.get("loginName").getAsString());
			staff.setCode(jsonObject.get("loginName").getAsString());
		}
		if(jsonObject.get("orgNodeCode") != null) {
			staff.setDepartmentCode(jsonObject.get("orgNodeCode").getAsString());
		}
		if(jsonObject.get("orgNodeName") != null) {
			staff.setDepartmentName(jsonObject.get("orgNodeName").getAsString());
		}
		if(jsonObject.get("orgNodeCode") != null) {
			staff.setDepartmentCode(jsonObject.get("orgNodeCode").getAsString());
		}
		if(jsonObject.get("emailIn") != null) {
			staff.setEmail(jsonObject.get("emailIn").getAsString());
		}
		if(jsonObject.get("emailIn") != null) {
			staff.setEmail(jsonObject.get("emailIn").getAsString());
		}
		if(jsonObject.get("cardno") != null) {
			staff.setIdcard(jsonObject.get("cardno").getAsString());
		}
		if(jsonObject.get("cardno") != null) {
			staff.setIdcard(jsonObject.get("cardno").getAsString());
		}
		/*if(jsonObject.get("code") != null) {
			staff.setCode(jsonObject.get("loginName").getAsString());
		}*/
		/*if(StringUtils.isEmpty(staff.getLoginid()) && StringUtils.isNotEmpty(staff.getCode())) {
			staff.setLoginid(jsonObject.get("code").getAsString());
		}*/
		if(jsonObject.get("name") != null) {
			staff.setName(jsonObject.get("name").getAsString());
		}
		if(jsonObject.get("name") != null) {
			staff.setLoginname(jsonObject.get("name").getAsString());
		}
		if(jsonObject.get("mobile") != null) {
			staff.setMobile(jsonObject.get("mobile").getAsString());
		}
		if(jsonObject.get("phone") != null) {
			staff.setPhone(jsonObject.get("phone").getAsString());
		}
		if(jsonObject.get("weight") != null) {
			staff.setWeight(jsonObject.get("weight").getAsInt());
		}
		if(jsonObject.get("status") != null) {
			staff.setStatus(jsonObject.get("status").getAsInt() == 1 ? 0 : 1);
		}
		return staff;
	}

}
